package sdk.org.apache.shiro.G2_使用.C07_1Web集成_登录和退出.services;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.titan.core.apidoc.annotations.ApiAuthor;
import com.titan.core.apidoc.annotations.ApiDescription;
import com.titan.core.apidoc.annotations.ApiEmail;
import com.titan.core.apidoc.annotations.ApiVersion;
import com.titan.core.base.BaseHtmlV8;
import com.titan.core.utils.data.AssertUtils;
import com.titan.core.utils.data.FormatUtils;
import com.titan.core.utils.data.StringUtils;
import com.titan.core.utils.file.JsonUtils;
import com.titan.core.utils.io.ConsoleUtils;
import com.titan.core.web.utils.RequestUtils;
import com.titan.services.GenerateCode.v8.ViewXML.tags.bootstrap4.Bootstrap4ButtonTagV8;
import com.titan.services.GenerateCode.v8.ViewXML.tags.bootstrap4.Bootstrap4CardTagV8;
import com.titan.services.GenerateCode.v8.ViewXML.tags.html.HtmlTagV8;
import com.titan.services.GenerateCode.v8.ViewXML.tags.html5.Html5FormTag;
import com.titan.services.GenerateCode.v8.ViewXML.tpl.form.FormGridField;
import com.titan.services.GenerateCode.v8.ViewXML.tpl.form.FormGridOption;
import com.titan.services.GenerateCode.v8.ViewXML.tpl.form.InputOption;
import com.titan.services.GenerateCode.v8.ViewXML.tpl.form.LabelOption;
import com.titan.services.GenerateCode.v8.ViewXML.tpl.options.ButtonOption;
import com.titan.services.GenerateCode.v8.ViewXML.tpl.options.CardOption;
import com.titan.services.GenerateCode.v8.ViewXML.tpl.options.PageOption;
import com.titan.services.GenerateCode.v8.common.enums.HtmlInputType;
import com.titan.services.GenerateCode.v8.common.utils.JsBuilderV8;

import sdk.org.apache.shiro.utils.ShiroUtils;


/**
 * This software is Copyright ©2018 ChengGong studio. All Rights Reserved.
 * The source code contained in this listing is proprietary to 周成功工作室.
 * Unauthorized copying, adaptation, distribution, use, or display is strictly prohibited.
 */
@ApiDescription("登录页面")
@ApiAuthor("周成功")
@ApiEmail("86898837@qq.com")
@ApiVersion("1.0.20190220")
@RestController
@RequestMapping("/login")
@SuppressWarnings("static-access")
public class LoginController extends BaseHtmlV8 {
    @RequestMapping("/page")
    public void page(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Html5FormTag form = this.tplT8.form(FormGridOption.$(), "formid"
                , FormGridField.$(4)
                , FormGridField.$label(8, LabelOption.$().setLabelId("error").setLabelClass("error text-left"), "", "")
                , FormGridField.$label(4, LabelOption.$(), "用户名", "username")
                , FormGridField.$input(6, InputOption.$(), "username", HtmlInputType.TEXT, false, 30, 30)
                , FormGridField.$label(4, LabelOption.$(), "密码", "password")
                , FormGridField.$input(6, InputOption.$(), "password", HtmlInputType.PASSWORD, false, 30, 30)
                );
        Bootstrap4ButtonTagV8 buttonOK = this.tplT8.button(ButtonOption.$(), "btnOK", "登录").onclick(JsBuilderV8.$().addLines(null
                , JsBuilderV8.urlForm("登录", "/login/action/ok", "formid"
                        , "var msg=response['row']['msg'];"
                        , "if(msg=='OK'){"
                        ,       "$$8.url.go('/login/success');"
                        , "}else{"
                        ,       "$('#error').html(msg);"
                        , "}"
                        )
                ));
        Bootstrap4CardTagV8 card = this.tplT8.card(CardOption.$(), "请登录", new Bootstrap4ButtonTagV8[]{buttonOK}, form);
        
        JsBuilderV8 style = JsBuilderV8.$().addLines(".error{color:red;}");
        JsBuilderV8 script = JsBuilderV8.$().addLines(this.NULL_LINE);
        PageOption spa = this.defaultContext(request, response);
        String htmlFull = this.page(spa, style, script, card);
        this.writeHtml(response, htmlFull);
    }

    
    @RequestMapping("/action/ok")
    public void action_ok(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String json = RequestUtils.getReader(request);
        AssertUtils.assertNotEmpty(json, "输入参数不能为空！");
        Map<String,Object> map = JsonUtils.toObject(json, Map.class);
        String username = FormatUtils.toString(map.get("username"));
        String password = FormatUtils.toString(map.get("password"));
        AssertUtils.assertNotEmpty(username, "输入参数username不能为空！");
        AssertUtils.assertNotEmpty(password, "输入参数password不能为空！");
        
        String error = null;
        try {
            ShiroUtils.login(username, password, true);
        } catch (UnknownAccountException e) {
            error = "用户名错误";
        } catch (IncorrectCredentialsException e) {
            error = "密码错误";
        } catch (AuthenticationException e) {
            //其他错误，比如锁定，如果想单独处理请单独catch处理
            error = "其他错误：" + e.getMessage();
        }
        
        if(StringUtils.isNotEmpty(error)) {//出错了，返回登录页面
            this.writeOK("msg", error, request, response);
        } else {//登录成功
            this.writeOK("msg", "OK", request, response);
        }
    }
    
    
    @RequestMapping("/success")
    public void success(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String username = ShiroUtils.getUsername(request);
        ConsoleUtils.log("username", username);
        
        HtmlTagV8 html = this.tplC8.html("欢迎"+username+"登录成功！<a href=\"/logout\">退出</a>");
        
        JsBuilderV8 style = JsBuilderV8.$().addLines(this.NULL_LINE);
        JsBuilderV8 script = JsBuilderV8.$().addLines(this.NULL_LINE);
        PageOption spa = this.defaultContext(request, response);
        String htmlFull = this.page(spa, style, script, html);
        this.writeHtml(response, htmlFull);
    }    
}
